home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1997 / MacHack 1997.toast / Hacks / Hacks ’96 / Booting Gallery / Booting Gallery (source) / Sources / Sound Source / SoundPlayer.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-06-22  |  3.7 KB  |  160 lines  |  [TEXT/BROW]

  1. #include "SoundPlayer.h"
  2. #include <assertmb.h>
  3.  
  4. #define min(a,b)        (((a)<(b))?(a):(b))
  5.  
  6. OSErr    SoundPlayer::InitEntryList()
  7. {
  8.     OSErr        err = noErr;
  9.     
  10.     err = fReceiverList.Reallocate(kNumChannels);
  11.     if(err == noErr){
  12.         for(short z = 0;z<kNumChannels;z++){
  13.             fReceiverList[z].receiver = NULL;
  14.             fReceiverList[z].readBuffer = NULL;
  15.             fReceiverList[z].curPlay = NULL;
  16.             fReceiverList[z].obj = this;
  17.         }
  18.         
  19.         for(short z = 0;z<kNumChannels;z++){
  20.             fReceiverList[z].receiver = new SReceiver(_ReadProc, (long)&fReceiverList[z], _CancelProc, kBufferSize);
  21.             err = fReceiverList[z].receiver->Initialize();
  22.             if(err == noErr){
  23.                 fReceiverList[z].receiver->Start();    
  24.             }
  25.         }
  26.     
  27.     }
  28.     
  29.     return err;
  30. }
  31.  
  32.  
  33. void    SoundPlayer::CancelProc(Entry* entry,SSCompletionProc ioCompletion,long completionData)
  34. {
  35.     (*ioCompletion)(completionData,userCanceledErr,0);
  36. }
  37.  
  38.  
  39. void    SoundPlayer::DoRead(Entry* entry)
  40. {
  41.     if(entry->curPlay != NULL){
  42.         UInt32        sizeWants = entry->readLength - entry->readPos;
  43.         UInt32        sizeHas = entry->curSize - entry->curPos;
  44.         UInt32        thisRead = min(sizeWants,sizeHas);
  45.         
  46.         BlockMoveData(entry->curPlay + entry->curPos,((Ptr)entry->readBuffer) + entry->readPos,thisRead);
  47.         entry->readPos += thisRead;
  48.         entry->curPos += thisRead;
  49.         
  50.         if((entry->readPos == entry->readLength) || (entry->curPos == entry->curSize)){
  51.             entry->readBuffer = NULL;
  52.             if(entry->curPos == entry->curSize){
  53.                 if(entry->loopQ){
  54.                     entry->curPos = 0;
  55.                 }else{
  56.                     entry->curPlay = NULL;
  57.                 }
  58.             }
  59.             (*entry->readCompletion)(entry->readCompletionData,noErr,entry->readPos);
  60.         }        
  61.     }
  62. }
  63.  
  64.  
  65. pascal OSErr    SoundPlayer::_ReadProc(void* buffer,long length,long refCon,
  66.         SSCompletionProc completion,long completionData)
  67. {
  68.     Entry*                entry = (Entry*)refCon;
  69.     SoundPlayer*        thisObj = (SoundPlayer*)entry->obj;
  70.     
  71.     thisObj->ReadProc(entry,buffer,length,completion,completionData);
  72.     
  73.     return noErr;
  74. }
  75.  
  76.  
  77. pascal void    SoundPlayer::_CancelProc(long refCon,SSCompletionProc ioCompletion,long completionData)
  78. {
  79.     Entry*                entry = (Entry*)refCon;
  80.     SoundPlayer*        thisObj = (SoundPlayer*)entry->obj;
  81.     
  82.     thisObj->CancelProc(entry,ioCompletion,completionData);
  83. }
  84.  
  85.  
  86. void    SoundPlayer::ReadProc(Entry* entry,void* buffer,long length,SSCompletionProc proc,long completionData)
  87. {
  88.     assert(entry->readBuffer == NULL);
  89.     entry->readBuffer = buffer;
  90.     entry->readLength = length;
  91.     entry->readCompletion = proc;
  92.     entry->readCompletionData = completionData;
  93.     entry->readPos = 0;
  94.     
  95.     DoRead(entry);
  96. }
  97.  
  98.  
  99. SoundPlayer::~SoundPlayer()
  100. {
  101.     for(short z = 0;z<fReceiverList.Size();z++){
  102.         delete fReceiverList[z].receiver;
  103.     }
  104. }
  105.  
  106.  
  107. SoundPlayer::SoundPlayer(OSErr& err)
  108. {
  109.     err = InitEntryList();
  110. }
  111.  
  112.  
  113. void    SoundPlayer::PlaySnd(Handle lockedSndHandle,long length,Boolean loopQ)
  114. {
  115.     Entry*            cur = NULL;
  116.     
  117.     for(short z = 0;z<fReceiverList.Size();z++){
  118.         if(fReceiverList[z].curPlay == NULL){
  119.             if(fReceiverList[z].readBuffer != NULL){
  120.                 cur = &fReceiverList[z];
  121.                 break;
  122.             }
  123.         }
  124.     }
  125.     
  126.     if(cur != NULL){
  127.         SHeader*        header;
  128.         long            offset;
  129.         
  130.         OSErr err = GetSoundHeaderOffset((SndListHandle)lockedSndHandle,&offset);
  131.         assert(err == noErr);
  132.         if(err == noErr){
  133.             header = (SHeader*) ((*lockedSndHandle)+offset);
  134.             
  135.             cur->receiver->SetSHeader(*header);
  136.  
  137.             switch(header->std.encode){
  138.                 case stdSH:
  139.                     cur->curPlay = (Ptr)header->std.sampleArea;
  140.                     cur->curSize = header->std.length;
  141.                     break;
  142.                 case extSH:
  143.                     cur->curPlay = (Ptr)header->ext.sampleArea;
  144.                     cur->curSize = header->ext.numChannels * header->ext.numFrames * (header->ext.sampleSize/8);
  145.                     break;
  146.                 case cmpSH:
  147.                     cur->curPlay = (Ptr)header->cmp.sampleArea;
  148.                     cur->curSize = header->cmp.numChannels * header->cmp.numFrames * (header->cmp.packetSize/8);
  149.                     break;
  150.                 default:
  151.                     assert(false);
  152.                     break;
  153.             }
  154.             cur->curPos = 0;
  155.             cur->loopQ = loopQ;
  156.             DoRead(cur);
  157.         }
  158.     }
  159. }
  160.